const WebSockets = require('ws');
const { wshandle, exit } = require("../utils/eventHandle");
const { queryStringToObject } = require("../utils/query");
const { unzip } = require('../utils/poka.js')
const { User, Message } = require('../model/index.js')
/**
 * 创建 WebSocket 服务器
 * @param {http.Server} server - HTTP 服务器实例
 * @returns {WebSockets.Server} WebSocket 服务器实例
 * 
 * 该函数用于创建一个 WebSocket 服务器，并处理客户端连接、消息接收和连接关闭等事件。
 * 在客户端连接时，会解析 URL 查询字符串并获取用户 ID 和用户名。
 * 支持处理 JSON 格式的消息，并根据消息类型执行不同的操作，如发送好友请求、接收好友请求和协作邀请等。
 * 在连接关闭时，会通知其他客户端该用户已退出。
 */
/**
 * 创建 WebSocket 服务器
 * @param {http.Server} server - HTTP 服务器实例
 * @returns {WebSockets.Server} - 返回创建的 WebSocket 服务器实例
 * 
 * 该函数用于创建一个 WebSocket 服务器，并处理客户端的连接、消息接收和连接关闭事件。
 * 在客户端连接时，会解析 URL 查询字符串并存储相关信息。
 * 收到消息时，会根据消息类型执行不同的逻辑，如发送好友请求、接收好友请求和协作邀请等。
 * 客户端连接关闭时，会通知其他客户端该用户已退出。
 */
// 用来管理各个表格在线协作的人数
let sheetArr = {}
const createWebSocketServer = (server) => {
  const servers = new WebSockets.Server({ server });
  servers.on('connection', (ws, req) => {
    const obj = queryStringToObject(req.url)
    ws.wid = obj.id;
    ws.wname = obj.name;
    ws.wsid = obj.sheetId

    // 处理收到的消息
    ws.on('message', (data) => {
      try {
        let message
        if (isJSON(data)) {
          message = JSON.parse(data.toString())
        }
        if (!isJSON(data)) {
          servers.clients.forEach((conn) => {
            if (conn.wid === ws.wid) return;
            if (conn.wsid != ws.wsid) return
            wshandle.call(conn, { id: ws.wid, name: ws.wname }, unzip(data));
          });
        } else {
          switch (message.type) {
            // 发送好友请求
            case '0':
              servers.clients.forEach((conn) => {
                if (conn.wid === message.receptionUser) {
                  conn.send(JSON.stringify({ sendUser: message.sendUser, receptionUser: message.receptionUser, type: message.type }))
                }
              });
              break;
            // 接收好友请求
            case "1":
              servers.clients.forEach(async (conn) => {
                if (conn.wid === message.receptionUser) {
                  let sendUser = await User.findById(message.sendUser)
                  let receptionUser = await User.findById(message.receptionUser)
                  sendUser.friendList.push(receptionUser._id)
                  receptionUser.friendList.push(sendUser._id)
                  sendUser.save()
                  receptionUser.save()
                  let body = {
                    sendUser: sendUser._id,
                    receptionUser: receptionUser._id,
                    content: sendUser.username + '同意了您的好友请求',
                    type: '1',
                    status: '0',
                    sendUserMessage: sendUser,
                    receptionUserMessage: receptionUser,
                  }
                  const receptionMessage = new Message(body)
                  await receptionMessage.save();
                  conn.send(JSON.stringify({ sendUser: message.sendUser, receptionUser: message.receptionUser, type: message.type }))
                }
              });
              break;
            // 协作邀请
            case "2":
              servers.clients.forEach(async (conn) => {
                if (conn.wid === message.receptionUser) {
                  let sendUser = await User.findById(message.sendUser)
                  let receptionUser = await User.findById(message.receptionUser)
                  let body = {
                    sendUser: sendUser._id,
                    receptionUser: receptionUser._id,
                    content: sendUser.username + '邀请您加入了《' + message.sheetName + '》文档',
                    type: '3',
                    status: '0',
                    sheetId: message.sheetId,
                    sendUserMessage: sendUser,
                    receptionUserMessage: receptionUser,
                  }
                  const receptionMessage = new Message(body)
                  await receptionMessage.save();
                  conn.send(JSON.stringify({ sendUser: sendUser, receptionUser: receptionUser, type: message.type, sheetId: message.sheetId, sheetName: message.sheetName }))
                }
              });
              break
            // 协作退出
            case "3":
              servers.clients.forEach((conn) => {
                if (conn.wid === ws.wid) return;
                // 使得 this 指向当前连接对象(这里也是需要统一操作对象)
                exit.call(conn, ws.wid);
              });
              break
            // 表格协作成员是否在线
            case "5":
              if (!sheetArr[message.sheetId]) {
                sheetArr[message.sheetId] = []
              }
              if (message.status) {
                let index = sheetArr[message.sheetId].findIndex((item) => item._id == message.userInfo._id)
                console.log(888888, sheetArr[message.sheetId]);
                if (index == -1) {
                  sheetArr[message.sheetId].push(message.userInfo)
                }
              } else {
                console.log(1111, message);
                sheetArr[message.sheetId] = sheetArr[message.sheetId].filter((item) => item._id != message.userInfo._id)
                console.log(2222, sheetArr[message.sheetId]);
              }
              servers.clients.forEach((conn) => {
                if (conn.wsid === message.sheetId) {
                  conn.send(JSON.stringify({ userInfo: sheetArr[message.sheetId], type: '5' }))
                }
              });
              break
            default:
          }
        }
      } catch (e) {
        console.log(e)
      }
    });
    // 处理连接关闭
    ws.on("close", () => {
    });
  });
  return servers;
}
function isJSON (str) {

  try {


    JSON.parse(str);


    return true;


  } catch (e) {


    return false;


  }


}
module.exports = createWebSocketServer;
